package com.dominator.serviceImpl;

import com.dominFramework.core.id.SystemIdUtils;
import com.dominFramework.core.typewrap.Dto;
import com.dominFramework.core.utils.SystemUtils;
import com.dominator.enums.ReqEnums;
import com.dominator.mybatis.dao.T_smsPO;
import com.dominator.repository.DaoSms;
import com.dominator.repository.DaoUser;
import com.dominator.service.ApiSmsService;
import com.dominator.utils.api.ApiMessage;
import com.dominator.utils.api.ApiMessageUtil;
import com.dominator.utils.api.ApiUtils;
import com.dominator.utils.dao.RedisUtil;
import com.dominator.utils.exception.ApiException;
import com.dominator.utils.sms.SmsUtils;
import com.dominator.utils.system.Constants;
import com.dominator.utils.system.PropertiesLoader;
import com.dominator.utils.system.VerifyCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class ApiSmsServiceImpl implements ApiSmsService {

    public static PropertiesLoader propertiesLoader = new PropertiesLoader("sysconfig.properties");

    @Autowired
    DaoUser userDao;

    @Autowired
    DaoSms smsDao;


    private static RedisUtil ru = RedisUtil.getRu();


    @Override
    public ApiMessage registerSms(Dto dto) throws ApiException {
        ApiMessage msg = new ApiMessage();
        ApiUtils.checkParam(dto, "phoneNum");
        if (SystemUtils.isNotEmpty(userDao.selectByPhoneNum(dto.getString("phoneNum")))) {
            throw new ApiException(ReqEnums.REQ_PHONE_EXSIT);
        }
        // 放入缓存
        String result = "";
        String verifyCode = VerifyCodeUtil.createVerifyCodeByLenth(6);

        result = ru.setex(dto.getString("phoneNum") + "_register", verifyCode, Constants.SMS_TIMES_INT);

        if ("OK".equals(result)) {
            log.info("验证码放入缓存成功：" + verifyCode);
        } else {
            log.error("验证码放入缓存失败!:" + result);
        }
        //生成验证码
        dto.put("verifyCode", verifyCode);
        // 保存数据库
        Integer sendtimes = smsDao.countByPhoneNum(dto.getString("phoneNum"));
        System.out.println(dto.getString("phoneNum") + "发送次数=" + sendtimes);
        if (sendtimes >= Integer.valueOf(propertiesLoader.getProperty("sms.send.max"))) {
            throw new ApiException(ReqEnums.REQ_SMS_LIMIT);
        }
        dto.put("stype", "1");
        return sendSms(dto);
    }

    @Override
    public ApiMessage loginSms(Dto dto) throws ApiException {
        ApiMessage msg = new ApiMessage();
        ApiUtils.checkParam(dto, "phoneNum");
//        if (SystemUtils.isEmpty(userDao.selectByPhoneNum(dto.getString("phoneNum")))) {
//            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
//        }
        // 放入缓存
        String result = "";
        String verifyCode = VerifyCodeUtil.createVerifyCodeByLenth(6);
        result = ru.setex(dto.getString("phoneNum") + "_login", verifyCode, Constants.SMS_TIMES_INT);
        if ("OK".equals(result)) {
            log.info("验证码放入缓存成功：" + verifyCode);
        } else {
            log.error("验证码放入缓存失败!:" + result);
        }
        //生成验证码
        dto.put("verifyCode", verifyCode);
        // 保存数据库
        Integer sendtimes = smsDao.countByPhoneNum(dto.getString("phoneNum"));
        System.out.println(dto.getString("phoneNum") + "发送次数=" + sendtimes);
        if (sendtimes >= Integer.valueOf(propertiesLoader.getProperty("sms.send.max"))) {
            throw new ApiException(ReqEnums.REQ_SMS_LIMIT);
        }
        dto.put("stype", "2");
        return sendSms(dto);
    }

    @Override
    public ApiMessage findPasswordSms(Dto dto) throws ApiException {
        ApiMessage msg = new ApiMessage();
        ApiUtils.checkParam(dto, "phoneNum");
        if (SystemUtils.isEmpty(userDao.selectByPhoneNum(dto.getString("phoneNum")))) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        }
        // 放入缓存
        String result = "";
        String verifyCode = VerifyCodeUtil.createVerifyCodeByLenth(6);
        result = ru.setex(dto.getString("phoneNum") + "_findPasswword", verifyCode, Constants.SMS_TIMES_INT);
        if ("OK".equals(result)) {
            log.info("验证码放入缓存成功：" + verifyCode);
        } else {
            log.error("验证码放入缓存失败!:" + result);
        }
        //生成验证码
        dto.put("verifyCode", verifyCode);
        // 保存数据库
        Integer sendtimes = smsDao.countByPhoneNum(dto.getString("phoneNum"));
        System.out.println(dto.getString("phoneNum") + "发送次数=" + sendtimes);
        if (sendtimes >= Integer.valueOf(propertiesLoader.getProperty("sms.send.max"))) {
            throw new ApiException(ReqEnums.REQ_SMS_LIMIT);
        }
        dto.put("stype", "3");
        return sendSms(dto);
    }

    @Override
    public ApiMessage setPayPasswordSms(Dto dto) throws ApiException {
        ApiMessage msg = new ApiMessage();
        ApiUtils.checkParam(dto, "phoneNum");
        if (SystemUtils.isEmpty(userDao.selectByPhoneNum(dto.getString("phoneNum")))) {
            throw new ApiException(ReqEnums.REQ_USER_NOT_EXSIT);
        }
        // 放入缓存
        String result = "";
        String verifyCode = VerifyCodeUtil.createVerifyCodeByLenth(6);
        result = ru.setex(dto.getString("phoneNum") + "_setPayPassword", verifyCode, Constants.SMS_TIMES_INT);
        if ("OK".equals(result)) {
            log.info("验证码放入缓存成功：" + verifyCode);
        } else {
            log.error("验证码放入缓存失败!:" + result);
        }
        //生成验证码
        dto.put("verifyCode", verifyCode);
        // 保存数据库
        Integer sendtimes = smsDao.countByPhoneNum(dto.getString("phoneNum"));
        System.out.println(dto.getString("phoneNum") + "发送次数=" + sendtimes);
        if (sendtimes >= Integer.valueOf(propertiesLoader.getProperty("sms.send.max"))) {
            throw new ApiException(ReqEnums.REQ_SMS_LIMIT);
        }
        dto.put("stype", "4");
        return sendSms(dto);
    }

    @Override
    public ApiMessage rechargeSms(Dto dto) throws ApiException {
        return null;
    }

    @Override
    public ApiMessage orderSms(Dto dto) throws ApiException {
        return null;
    }

    @Override
    public ApiMessage verifySms(Dto dto) throws ApiException {
        ApiMessage msg = new ApiMessage();
        ApiUtils.checkParam(dto, "phoneNum,verifyType,verifyCode");

        String verifyCode = "";
        switch (dto.getInteger("verifyType")) {
            case 1:
                verifyCode = ru.get(dto.getString("phoneNum") + "_register");
                break;
            case 2:
                verifyCode = ru.get(dto.getString("phoneNum") + "_login");
                break;
            case 3:
                verifyCode = ru.get(dto.getString("phoneNum") + "_findPassword");
                break;
            case 4:
                verifyCode = ru.get(dto.getString("phoneNum") + "_setPayPassword");
                break;
        }
        if (SystemUtils.isEmpty(verifyCode)) {
            log.error("redis未查询到验证码，查询数据库！");
            T_smsPO sms = smsDao.selectByCodeStype(dto.getString("verifyCode"), dto.getString("verifyType"));
            if (SystemUtils.isEmpty(sms)) {
                throw new ApiException(ReqEnums.REQ_WRONG_VERIFY_CODE);
            }
            verifyCode = sms.getCode();
            log.info("mysql已经查询到验证码" + verifyCode);

        } else {
            log.info("redis已经查询到验证码" + verifyCode);
        }

        if (!dto.getString("verifyCode").equals(verifyCode)) {
            log.error("验证码错误");
            throw new ApiException(ReqEnums.REQ_WRONG_VERIFY_CODE);
        }
        return msg;
    }


    public ApiMessage sendSms(Dto dto) throws ApiException {
        ApiMessage msg = new ApiMessage();
        //保存数据库
        T_smsPO sms = new T_smsPO();
        sms.setId(SystemIdUtils.uuid());
        sms.setCreate_time(new Date());
        sms.setIp(dto.getString("ip"));
        sms.setMobile(dto.getString("phoneNum"));
        sms.setStype(dto.getString("stype"));
        sms.setDevice_id(dto.getString("deviceId"));
        sms.setIs_valid("1");
        sms.setCode(dto.getString("verifyCode"));
        Integer res = smsDao.insertSelective(sms);
        if (res == 1) {
            log.info("开始调用发短信！！！！！");
            try {
                SmsUtils.sendSms(dto);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ApiException(ReqEnums.REQ_SMS_ERROR);
            }
            log.info("调用短信结束！！！！！！");
            return ApiMessageUtil.success();
        } else {
            throw new ApiException(ReqEnums.REQ_SMS_ERROR);
        }
    }

}
